#ifndef __UPPER_COMMUNITY_H__
#define __UPPER_COMMUNITY_H__
#include "ti_msp_dl_config.h"
#include "stdbool.h"


#define FRAME_HEADER 	0xA5

/**********RECEIVE_CMD************/
#define CMD_PID_DATA	0x01
#define CMD_FB_DATA		0x02
/***********SEND_CMD************/
#define MODE_NORMAL		0x11
#define MODE_SAVE_POINT	0x12

#define CMD_CHG_MD_1	0xA1
#define CMD_CHG_MD_2	0xA2
#define CMD_CHG_MD_3	0xA3
#define CMD_CHG_MD_4	0xA4

#define CMD_START_WORK	0xA5

#define CMD_SPOINT_1	0x01
#define CMD_SPOINT_2	0x02
#define CMD_SPOINT_3	0x03
#define CMD_SPOINT_4	0x04

/***********FRAME_FOOTER************/
#define FRAME_FOOTER_0	0xA6
#define FRAME_FOOTER_1	0x5A


// define the receive status
typedef enum {
    STATE_HEADER = 0,
    STATE_CMD,
    STATE_DATA,
    STATE_FOOTER
} RxState;

#pragma pack(push,1)
typedef struct {
    uint8_t header;     // 
    uint8_t cmd;        // 
    union {             // 
        struct {
            float data_yaw;
            float data_pitch;
        } float_data;
        char feedback_data[8]; // 8
    } data_domain;
    uint8_t footer[2];  // 
} community_frame_t;

typedef struct
{
	uint8_t header;
	uint8_t mode;
	uint8_t cmd;
	uint8_t footer[2];
}send_frame_t;

#define FRAME_SIZE sizeof(community_frame_t)
#define RING_BUFFER_SIZE 128

//define the receive raw data
typedef struct {
    RxState state;
    uint8_t buffer[FRAME_SIZE];
    size_t index;
    community_frame_t *frame;
} RxContext;

//define the ring buffer
typedef struct
{
	uint8_t buffer[RING_BUFFER_SIZE];
	uint8_t	head;
	uint8_t tail;
	uint8_t size;
}ring_buffer_t;

#pragma pack(pop)


void com_frame_parse(community_frame_t * frame);

void com_rx_context_init(RxContext *ctx);

int com_process_rx_byte(RxContext *ctx, uint8_t byte);

int com_frame_send(uint8_t mode, uint8_t cmd);

void com_ring_buffer_init(ring_buffer_t *rb);
bool com_ring_buffer_is_full(ring_buffer_t *rb);
bool com_ring_buffer_is_empty(ring_buffer_t *rb);
bool com_ring_buffer_put(ring_buffer_t *rb,uint8_t data);
bool com_ring_buffer_get(ring_buffer_t *rb,uint8_t *data);
void com_process_rx_data(ring_buffer_t *fifo,RxContext *ctx);

#endif
